package com.sinotrans.auth.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import com.sinotrans.common.aop.RoleAspect;
import com.sinotrans.common.aop.SwaggerApiAspect;
import com.sinotrans.common.config.CacheConfiguration;
import com.sinotrans.common.exception.BusinessException;
import com.sinotrans.common.security.AuthFeignTemplate;
import com.sinotrans.common.security.AuthRestTemplate;
import com.sinotrans.common.security.DigestSignature;
import com.sinotrans.logger.aop.LogAspect;
import com.sinotrans.logger.filter.LogFilter;

import feign.RequestInterceptor;

@EnableCaching
@Configuration
public class CommonConfig extends CacheConfiguration {

	@Bean
	public DigestSignature digestSignature() throws BusinessException {
		return new DigestSignature();
	}

	@Bean
	public RoleAspect roleAspect() throws BusinessException {
		return new RoleAspect(digestSignature());
	}

	/*
	 * LogFilter
	 */
	@Bean
	public FilterRegistrationBean<LogFilter> registerAuthFilter() {
		LogFilter logFilter = new LogFilter();
		logFilter.setMaxLength(10000);
		String[] uriPatterns = { "*.dwr", "*.do", "*.action" };
		logFilter.setUriPatterns(uriPatterns);
		String[] excludeUriPatterns = { "*.html", "*.js" };
		logFilter.setExcludeUriPatterns(excludeUriPatterns);
		//
		FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<LogFilter>();
		registration.setFilter(logFilter);
		registration.addUrlPatterns("/*");
		registration.setName("logFilter");
		// 值越小，Filter越靠前。
		registration.setOrder(1);
		return registration;
	}

	/*
	 * 切面配置
	 */
	@Aspect
	private class LogAspectConfig extends LogAspect {

		@Around("@annotation(com.sinotrans.logger.api.LogMethod)")
		public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
			return super.logAround(pjp);
		}
	}

	/*
	 * 日志切面
	 */
	@Bean
	public LogAspectConfig logAspectConfig() {
		return new LogAspectConfig();
	}

	/*
	 * Swagger切面
	 */
	@Bean
	public SwaggerApiAspect swaggerUiAspect() {
		return new SwaggerApiAspect();
	}

	@Bean
	@LoadBalanced
	public RestTemplate restTemplate() throws BusinessException {
		return new AuthRestTemplate(digestSignature());
	}

	@Bean
	public RequestInterceptor feignTemplate() throws BusinessException {
		return new AuthFeignTemplate(digestSignature());
	}

}
